package org.cnbi.utils.xml;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.dom4j.Document;
import org.dom4j.Element;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.cnbi.utils.pojo.dash.ItemBean;
import org.cnbi.utils.pojo.dash.ModelBean;
import org.cnbi.utils.pojo.dash.UserDefinedFormulaBean;
import org.cnbi.utils.string.StringUtil;
import org.cnbi.utils.xml.XMLUtils;
import org.cnbi.utils.xml.support.XmlParserSupport;

/**
 * 预测模型xml文件解析类
 * Copyright © 2014中国经邦. All rights reserved.
 * @author 龚佳新
 * @date 2014年5月6日上午11:41:11
 * @cnbi-utils
 */

public class YcDashXmlParser implements XmlParserSupport{
	
	protected static  final Log logger = LogFactory.getLog(YcDashXmlParser.class);

	private Document doc;

	public Map<String, Object> toolsMap;
	
	public List<Object> slider;
	
	public List<Object> progress;
	
	public List<Object> tips ;

	public StringBuffer repalceVar;

	public Document getDoc() {
		return doc;
	}

	public void setDoc(Document doc) {
		this.doc = doc;
	}
	public YcDashXmlParser(){}
	public YcDashXmlParser(Document doc){
		this.doc = doc;
		
	}

	@Override
	public Object execute() throws Exception {//sheet
		Element rootEl = this.doc.getRootElement(),sheetEl = XMLUtils.getElementById(SHEET, this.doc);
		if(null != sheetEl){
		}
		Element itemsEl = XMLUtils.getElementById(ITEMS, this.doc), // 项目节点
		assistItemsEl = XMLUtils.getElementById(ASSIST_ITEMS, this.doc), // 辅助项目节点
		formulasEl = XMLUtils.getElementById(FOUMULAS, this.doc), // 公式节点
		dataEl = XMLUtils.getElementById(DATAS, this.doc),// 自定义数据
	    chartEl = XMLUtils.getElementById(CHART, this.doc),//图组件
		industryParamsEl = XMLUtils.getElementById(INDUSTRY_PARAMS, this.doc),// industry行业参数节点
		
		tipsEl = XMLUtils.getElementById("tips", this.doc); // tips节点
		String id = rootEl.attributeValue(ID),
		 title = rootEl.attributeValue(TITLE),
		 dataType = rootEl.attributeValue("dataType"),//factType="fact_A,fact_B"
	      subject = rootEl.attributeValue("subject"),//factType="fact_A,fact_B"
		 factType = rootEl.attributeValue("factType");//factType="fact_A,fact_B"
		ModelBean bean = new ModelBean(id, title);
		if(!StringUtil.isBlank(dataType))bean.setDataType(dataType.trim());
		if(!StringUtil.isBlank(factType))bean.setFactType(factType.trim());
		if(!StringUtil.isBlank(subject))bean.setSubject(subject.trim());
		toolsMap = new HashMap<String, Object>();
		List<Object> items = null;
		Map<Object, List<Object>> assistItemsMap = null;
		Map<Object, List<Object>> formula = null;
		Map<Object, List<Object>> industyMap = null;
		if (null == itemsEl) {
		} else {
			items = getItems(itemsEl);
			if (null != slider && slider.size() != 0)
				bean.setItems(items);
		}
		if (null == assistItemsEl) {
		} else {
			assistItemsMap = getCommonItems(assistItemsEl);
			if (null != assistItemsMap && assistItemsMap.size() != 0)
				bean.setAssistItems(assistItemsMap);
		}
		if (null == formulasEl) {
		} else {
			formula = getCommonItems(formulasEl);
			if (null != formula && formula.size() != 0)
				bean.setFormula(formula);
		}
		if (null == industryParamsEl) {
			
		} else {
			industyMap = getCommonItems(industryParamsEl);
			if (null != industyMap && industyMap.size() != 0)
				bean.setIndustry(industyMap);
		}
		if (null != repalceVar && repalceVar.length() > 0) {
			repalceVar.delete(0, 1);
			bean.setRepalceVar(repalceVar.toString());
		}
		if(null!=dataEl){
			String data = dataEl.getStringValue();
			data =org.cnbi.utils.string.StringUtil.replaceBlank(data);
			bean.setDatas(data);
		}
		if(null!=chartEl){
			 List<Object> chart   = getItems(chartEl);
			 bean.setChart(chart);
		}
		if(null!=tipsEl){
			 List<Object> tips   = getItems(tipsEl);
			 bean.setTips(tips);
		}
		bean.setToolsMap(toolsMap);
		bean.setSlider(slider);
		bean.setProgress(progress);
		return bean;
	}

	/**
	 * 对itemEl_List进行配置
	 * @param contentEl
	 * @return
	 */
	private List<Object> getItems(Element contentEl) {
		return getItemsList(contentEl);
	}
	/**
	 * 对assistItems进行配置
	 * 
	 * @param contentEl
	 * @return
	 */
	private Map<Object, List<Object>> getCommonItems(Element contentEl) {
		Map<Object, List<Object>> map = new LinkedHashMap<Object, List<Object>>();
		List<Element> ele_list = contentEl.elements(ITEMS);// contentEl.elements("assist_Items");
		String itemsId = XMLUtils.attr(contentEl, ID);
		for (Element itemsEl : ele_list) {
			String id = XMLUtils.attr(itemsEl, ID);
			List<Object> itemsList = getItemsList(itemsEl);
			if(itemsId.equals(INDUSTRY_PARAMS)){//new ItemBean(id,scode,sname)
				String sname = XMLUtils.attr(itemsEl, "sname"),scode = XMLUtils.attr(itemsEl, "scode");
				map.put(id+"_"+scode+"_"+sname, itemsList);
			}else{
				map.put(id, itemsList);
			}
			
		}
		return map;
	}

	private List<Object> getItemsList(Element contentEl) {
		List<Element> itemEl_List = contentEl.elements(ITEM_1);
		if (null == itemEl_List || itemEl_List.size() == 0) {
			//logger.info(contentEl.attributeValue("id")+"系统检测到没有配置项目节点");
			return null;
		}
		List<Object> items = new ArrayList<Object>();
		for (Element itemEl : itemEl_List) {
			Object b = getItemBean(itemEl);
			items.add(b);
		}
		return items;
	}

	private Object getItemBean(Element element) {
		String scode = XMLUtils.attr(element, SCODE), sname = XMLUtils.attr(element, SNAME),
			id = XMLUtils.attr(element, ID), exp = XMLUtils.attr(element, EXP),type = XMLUtils.attr(element, "type"),
			mins = XMLUtils.attr(element, "min"), maxs = XMLUtils.attr(element,"max"),
			subject = XMLUtils.attr(element, "subject"), fact = XMLUtils.attr(element,"fact"),period = XMLUtils.attr(element,"period"),
		level = XMLUtils.attr(element,LEVAL);
		if(sname.equals(""))sname = XMLUtils.attr(element, "name");
		if (!level.equals("")) {// {SCODE:EL}
			String value = XMLUtils.attr(element, VALUE);
			ItemBean b = new ItemBean();
			b.setId(level);
			b.setScode(value);
			b.setSname(sname);
			return b;
		}
		int min = -100000,max=100000;
		if(!mins.equals("")){
			min = Integer.parseInt(mins);
		}
        if(!maxs.equals("")){
        	max = Integer.parseInt(maxs);
		}
        String attr =  element.getStringValue();
        ItemBean itemBean = new ItemBean(id, scode, sname,min,max,type);
        
        if(!attr.equals("")){
        	attr = org.cnbi.utils.string.StringUtil.replaceLeftAndRightBlank(attr);
        	itemBean.setAttr(attr);
        }
        if(!subject.equals("")){
        	itemBean.setSubject(subject);
        }
        if(!fact.equals("")){
        	itemBean.setFact(fact);
        }
        if(!period.equals("")){
        	itemBean.setPeriod(period);
        }
		toolsMap.put(id,itemBean);
		if (exp.equals("")){
			addBeanToList(type, itemBean);
			return itemBean;
		} else {
			String params = XMLUtils.attr(element, PARAMS), formula = XMLUtils.attr(element,FORMULA), 
			//replaceVar = XMLUtils.attr(element, REPLACEVAR),
			tipss = XMLUtils.attr(element,"tips");
			UserDefinedFormulaBean bean = new UserDefinedFormulaBean();
			bean.setId(id);
			bean.setScode(scode);
			bean.setType(type);
			bean.setSname(sname);
			bean.setFormula(formula);
			bean.setExp(exp);
			bean.setParams(params.split("\\,"));
			
			if(tipss.equals("1")){
				String f = element.getStringValue();
				f = org.cnbi.utils.string.StringUtil.replaceLeftAndRightBlank(f);
				if(null == tips) tips = new ArrayList<Object>();
				bean.setFormula(f);
				tips.add(bean);
			}else{
				addBeanToList(type, bean);
			}
			return bean;
		}
	}

	/**
	 * @param type
	 * @param itemBean
	 */
	private void addBeanToList(String type, Object itemBean) {
		if(type.equals("slider")){
			if(null == slider) slider = new ArrayList<Object>();
			slider.add(itemBean);
		}else if(type.equals("progress")){
			if(null == progress) progress = new ArrayList<Object>();
			progress.add(itemBean);
		}/*else if(type.equals("chart")){
			if(null == chart) chart = new ArrayList<Object>();
			chart.add(itemBean);
		}*/
	}

	
}
